FOLLOW-UP – Add preamble to each MakeData script

Goals

Initialize metadata for the GRS analyses Identify individuals who are eligible for analysis based on having known Celiac status and no known first degree relatives in the analysis cohort

Load frequently used packages

library(openxlsx)
library(ggrepel)
library(dplyr)
library(tidyr)
library(data.table)
library(broom)
library(broomExtra)
library(tibble)
library(sjstats)
library(car)
library(lme4)
Loading required package: Matrix
Warning: package ‘Matrix’ was built under R version 4.1.2

Attaching package: ‘Matrix’

The following objects are masked from ‘package:tidyr’:

    expand, pack, unpack
library(lmerTest)

Attaching package: ‘lmerTest’

The following object is masked from ‘package:lme4’:

    lmer

The following object is masked from ‘package:stats’:

    step
library(ggplot2)
library(tibble)
library(modelr)
library(tidyverse)
#library(miceadds)
library(ggforce)
require(openxlsx)
library(tidyverse)
library(caret)
library(glmnet)
Loaded glmnet 4.1-3
library(ggplot2)
select <- dplyr::select
filter <- dplyr::filter

Define in/out directory

dir <- "/Users/shawjes/Dropbox/EspinosaGroup/ANALYSIS/Celiac_MultiOmics/GRS/DSMIG_Shared/Manuscript_Figure1/Data"

Load MEGA to HTP ID key

setwd(dir)
Warning: The working directory was changed to /Users/shawjes/Dropbox/EspinosaGroup/ANALYSIS/Celiac_MultiOmics/GRS/DSMIG_Shared/Manuscript_Figure1/Data inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
MEGA.IDkey <- fread("MEGA_041822_MEGA2_to_HTP_ID_key_v0.1_JRS.csv")

MEGA.IDkey

Read in latest version of the meta/comorb data

setwd("/Users/shawjes/Dropbox/EspinosaGroup/DATA_MAIN/META/OneDrive_1_2-17-2022")
Warning: The working directory was changed to /Users/shawjes/Dropbox/EspinosaGroup/DATA_MAIN/META/OneDrive_1_2-17-2022 inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
meta_comorb.022021 <- fread("HTP_CLEANED_02_2021_v0.5_COMORB_MASTER_RecordID_vs_LabID.Labels.tsv") %>%
  select(FamilyID, RecordID, LabID, Age_at_visit, Sex, Karyotype, everything()) %>%
  mutate(Celiac = as.numeric(`Celiac disease`))

meta_comorb.022021

Put the column names representing identifiers into a vector for reference below

ID_colnames <- c("FamilyID", "RecordID", "MEGA.FID", "MEGA.IID", "MEGA.LabID")

Make subset of meta/comorb dataset specific to Visit 1 for T21s with complete Celiac status

meta_comorb.T21_visit1_Celiac <- meta_comorb.022021 %>%
  filter(Karyotype == "T21" &
           !is.na(LabID) & Event_name == "Visit 1" & # Assuming that Celiac status for HTP was ascertained as of participant visit 1
           !is.na(`Celiac disease`)) %>%
  select(colnames(meta_comorb.022021)[1:18],
         `Celiac disease`, Celiac,
         everything()) %>%
  rename(Age_at_visit1 = Age_at_visit)

meta_comorb.T21_visit1_Celiac

Make meta/comorb dataset specific to visit 1 for T21s with complete Celiac status and complete MEGA genotyping

#colnames(MEGA.IDkey)
#colnames(meta_comorb.022021)

meta.MEGA.T21_visit1_Celiac <- MEGA.IDkey %>%
  filter(HTP_participant == "Yes") %>%
  select(-c(HTP_participant)) %>%
  left_join(meta_comorb.T21_visit1_Celiac %>% mutate(In_T21celiac_metadata = 1),
            by = c("FamilyID", "RecordID"))
# Note: Here I'm joining to the metadata corresponding to visit 1, when Celiac status was determined for the purposes of the study. 
# For this reason I am not including LabID as a join by variable.

meta.MEGA.T21_visit1_Celiac %>%
  group_by(In_plink_fam, In_T21celiac_metadata) %>%
  summarise(N = n())
`summarise()` has grouped output by 'In_plink_fam'. You can override using the `.groups` argument.
print("6 participants have complete genotype data but incomplete Celiac status.")
[1] "6 participants have complete genotype data but incomplete Celiac status."
meta.MEGA.T21_visit1_Celiac01 <- meta.MEGA.T21_visit1_Celiac %>%
  filter(!is.na(In_plink_fam) & !is.na(In_T21celiac_metadata)) %>%
  select(-c(In_plink_fam, In_T21celiac_metadata))

meta.MEGA.T21_visit1_Celiac01

Define custom function for mode

# Create the function.
getmode <- function(v) {
   uniqv <- unique(v)
   uniqv[which.max(tabulate(match(v, uniqv)))]
}

Check that each individual was only genotyped one time

if( (meta.MEGA.T21_visit1_Celiac01 %>%
     group_by(RecordID) %>%
     summarise(N = n()) %>%
     arrange(desc(N)) %>%
     ungroup() %>%
     summarise(var(N)) == 0) ) {"Great, all RecordIDs have the same number of rows of data."} else {
       print("Oops, RecordIDs have varying number of rows.");
       temp <- meta.MEGA.T21_visit1_Celiac01 %>%
         group_by(RecordID) %>%
         summarise(N_rows = n()) %>%
         arrange(desc(N_rows)) %>%
         ungroup() %>%
         mutate(min.N_rows = min(N_rows),
                max.N_rows = max(N_rows),
                mode.N_rows = getmode(N_rows),
                N_rows_Equal_mode = ifelse(N_rows == mode.N_rows, 1, 0),
                N_rows_NotEqual_mode = ifelse(N_rows != mode.N_rows, 1, 0))
       print(paste("N = ", sum(temp$N_rows_Equal_mode), " RecordIDs with N_rows = ", unique(temp$mode.N_rows), sep = ""))
       print(paste("N = ", sum(temp$N_rows_NotEqual_mode),
                   " RecordIDs with mean N_rows = ",
                   mean((temp %>% filter(N_rows!=mode.N_rows))$N_rows),
                   "\nPrinting problematic RecordIDs now. Problems stored in `problems`",
                   sep = ""))
       #print(paste("N = ", sum(temp$N_Equal_mode[1]), " samples with nrow = ", temp$N, sep = ""))
       
       problems <- temp %>%
         filter(N_rows != mode.N_rows) %>%
         select(RecordID, N_rows, mode.N_rows) %>%
         left_join(meta.MEGA.T21_visit1_Celiac01, by = "RecordID") %>%
         select(FamilyID, RecordID, MEGA.IID, MEGA.LabID, N_rows, mode.N_rows) %>%
         unique()
       
       print(problems)
     }
[1] "Oops, RecordIDs have varying number of rows."
[1] "N = 205 RecordIDs with N_rows = 1"
[1] "N = 5 RecordIDs with mean N_rows = 2\nPrinting problematic RecordIDs now. Problems stored in `problems`"
print("Based on this output, five samples were genotyped twice in different wells.")
[1] "Based on this output, five samples were genotyped twice in different wells."
print("Below we will clean the data to keep only the first sample well for each RecordID.")
[1] "Below we will clean the data to keep only the first sample well for each RecordID."

Since some RecordIDs/LabIDs were genotyped in more than one well, sort MEGA.IID alphabetically within RecordID and then keep the first MEGA.IID

Check if now each RecordID has only one MEGA.IID

print(paste("Rows in `mega_Snp_dosage.clean01` = ", meta.MEGA.T21_visit1_Celiac01 %>% select(RecordID, MEGA.IID) %>% unique() %>% nrow(), sep = ""))
[1] "Rows in `mega_Snp_dosage.clean01` = 215"
print(paste("Rows in `mega_Snp_dosage.clean02` = ", meta.MEGA.T21_visit1_Celiac02 %>% filter(EXCLUDE_from_analysis == 0) %>% select(RecordID, MEGA.IID) %>% unique() %>% nrow(), sep = ""))
[1] "Rows in `mega_Snp_dosage.clean02` = 210"
if( (meta.MEGA.T21_visit1_Celiac02 %>% filter(EXCLUDE_from_analysis == 0) %>%
     group_by(RecordID) %>%
     summarise(N = n()) %>%
     arrange(desc(N)) %>%
     ungroup() %>%
     summarise(var(N)) == 0) ) {"Great, now all RecordIDs have the same number of rows of data."} else {
       print("Oops, RecordIDs have varying number of rows.");
       temp <- meta.MEGA.T21_visit1_Celiac02 %>% filter(EXCLUDE_from_analysis == 0) %>%
         group_by(RecordID) %>%
         summarise(N_rows = n()) %>%
         arrange(desc(N_rows)) %>%
         ungroup() %>%
         mutate(min.N_rows = min(N_rows),
                max.N_rows = max(N_rows),
                mode.N_rows = getmode(N_rows),
                N_rows_Equal_mode = ifelse(N_rows == mode.N_rows, 1, 0),
                N_rows_NotEqual_mode = ifelse(N_rows != mode.N_rows, 1, 0))
       print(paste("N = ", sum(temp$N_rows_Equal_mode), " RecordIDs with N_rows = ", unique(temp$mode.N_rows), sep = ""))
       print(paste("N = ", sum(temp$N_rows_NotEqual_mode),
                   " RecordIDs with mean N_rows = ",
                   mean((temp %>% filter(N_rows!=mode.N_rows))$N_rows),
                   "\nPrinting problematic RecordIDs now. Problems stored in `problems`",
                   sep = ""))
       #print(paste("N = ", sum(temp$N_Equal_mode[1]), " samples with nrow = ", temp$N, sep = ""))
       
       problems <- temp %>%
         filter(N_rows != mode.N_rows) %>%
         select(RecordID, N_rows, mode.N_rows) %>%
         left_join(meta.MEGA.T21_visit1_Celiac02, by = "RecordID") %>%
         select(FamilyID, RecordID, MEGA.IID, MEGA.LabID, N_rows, mode.N_rows) %>%
         unique()
       
       print(problems)
     }
[1] "Great, now all RecordIDs have the same number of rows of data."

If all of the following equal the same number of rows, then this dataframe now represents genotyping only once per individual

meta.MEGA.T21_visit1_Celiac02 %>% filter(EXCLUDE_from_analysis == 0) %>%
  select(FamilyID, RecordID, MEGA.IID, MEGA.LabID) %>%
  unique() %>%
  nrow()
[1] 210
meta.MEGA.T21_visit1_Celiac02 %>% filter(EXCLUDE_from_analysis == 0) %>%
  select(RecordID, MEGA.IID, MEGA.LabID) %>%
  unique() %>%
  nrow()
[1] 210
meta.MEGA.T21_visit1_Celiac02 %>% filter(EXCLUDE_from_analysis == 0) %>%
  select(MEGA.IID, MEGA.LabID) %>%
  unique() %>%
  nrow()
[1] 210
meta.MEGA.T21_visit1_Celiac02 %>% filter(EXCLUDE_from_analysis == 0) %>%
  select(MEGA.LabID) %>%
  unique() %>%
  nrow()
[1] 210
meta.MEGA.T21_visit1_Celiac02 %>% filter(EXCLUDE_from_analysis == 0) %>%
  select(MEGA.IID) %>%
  unique() %>%
  nrow()
[1] 210
meta.MEGA.T21_visit1_Celiac02 %>% filter(EXCLUDE_from_analysis == 0) %>%
  select(RecordID) %>%
  unique() %>%
  nrow()
[1] 210
meta.MEGA.T21_visit1_Celiac02 %>% filter(EXCLUDE_from_analysis == 0) %>%
  select(FamilyID, RecordID, MEGA.IID) %>%
  unique() %>%
  nrow()
[1] 210
meta.MEGA.T21_visit1_Celiac02 %>% filter(EXCLUDE_from_analysis == 0) %>%
  select(FamilyID, RecordID) %>%
  unique() %>%
  nrow()
[1] 210
meta.MEGA.T21_visit1_Celiac02 %>% filter(EXCLUDE_from_analysis == 0) %>%
  select(RecordID, MEGA.IID) %>%
  unique() %>%
  nrow()
[1] 210
print("If all of the numbers printed above equal the same number of rows, then this dataframe now represents genotyping only once per individual.")
[1] "If all of the numbers printed above equal the same number of rows, then this dataframe now represents genotyping only once per individual."
print("Good.")
[1] "Good."

Final check that all RecordIDs now have only 1 MEGA.IID after using the EXCLUDE_from_analysis column to filter

meta.MEGA.T21_visit1_Celiac02 %>% filter(EXCLUDE_from_analysis == 0) %>%
  select(RecordID, MEGA.IID) %>%
  unique() %>%
  group_by(RecordID) %>%
  summarise(N = n()) %>%
  arrange(desc(N)) %>%
  left_join(meta.MEGA.T21_visit1_Celiac02, by = "RecordID") %>%
  filter(N > 1)


print("Good. All RecordIDs have only 1 MEGA.IID after applying the EXCLUDE_from_analysis filter.")
[1] "Good. All RecordIDs have only 1 MEGA.IID after applying the EXCLUDE_from_analysis filter."

Check for twins and other relateds

If there are relateds in the dataset after applying the EXCLUDE filter, first prioritize keeping Celiac cases, then randomly choose one IID per FamilyID to retain for analysis

meta.MEGA.T21_visit1_Celiac02 %>% filter(EXCLUDE_from_analysis == 0) %>%
  select(FamilyID, RecordID) %>% #, MEGA.IID, MEGA.LabID) %>%
  unique() %>%
  group_by(FamilyID) %>%
  summarise(N_RecordIDs_per_FamilyID = n()) %>%
  ungroup() %>%
  arrange(desc(N_RecordIDs_per_FamilyID)) %>%
  filter(N_RecordIDs_per_FamilyID > 1)

relateds <- meta.MEGA.T21_visit1_Celiac02 %>% filter(EXCLUDE_from_analysis == 0) %>%
  select(FamilyID, RecordID) %>% #, MEGA.IID, MEGA.LabID) %>%
  unique() %>%
  group_by(FamilyID) %>%
  summarise(N_RecordIDs_per_FamilyID = n()) %>%
  ungroup() %>%
  arrange(desc(N_RecordIDs_per_FamilyID)) %>%
  filter(N_RecordIDs_per_FamilyID > 1) %>%
  left_join(meta.MEGA.T21_visit1_Celiac02, by = "FamilyID") %>%
  select(FamilyID, N_RecordIDs_per_FamilyID, RecordID, MEGA.IID, MEGA.LabID, EXCLUDE_from_analysis, Celiac, Sex, Age_at_visit1) %>%
  unique() %>%
  #left_join(meta_comorb.022021, by = c("FamilyID", "RecordID", "MEGA.LabID"="LabID")) %>%
  group_by(FamilyID) %>%
  arrange(desc(Celiac)) %>%
  mutate(index_within_FamilyID = row_number()) %>%
  ungroup() %>%
  select(FamilyID, N_RecordIDs_per_FamilyID, index_within_FamilyID, Celiac, Sex, Age_at_visit1, everything()) %>%
  arrange(FamilyID, index_within_FamilyID)

relateds

relateds %>%
  select(FamilyID, index_within_FamilyID, EXCLUDE_from_analysis, Celiac, Sex) %>%
  unique() %>%
  group_by(FamilyID, Sex) %>%
  summarise(N = n())
`summarise()` has grouped output by 'FamilyID'. You can override using the `.groups` argument.
print("Decision: From FamilyID F0348 (2 individuals), keep INVTH328HA9 because this person is a Celiac case.")
[1] "Decision: From FamilyID F0348 (2 individuals), keep INVTH328HA9 because this person is a Celiac case."
print("Note: All other familys have only males or only females, except for one family with 1 of each.")
[1] "Note: All other familys have only males or only females, except for one family with 1 of each."
print("Decision: Therefore, from all other FamilyIDs, randomly select one individual to remain in the analysis.")
[1] "Decision: Therefore, from all other FamilyIDs, randomly select one individual to remain in the analysis."
set.seed(1234) # Set seed for randomly shuffling rows
relateds_to_keep = relateds[sample(1:nrow(relateds)), ] %>%
  group_by(FamilyID) %>%
  mutate(random_index = row_number()) %>%
  ungroup() %>%
  mutate(Keep = ifelse(FamilyID == "F0348" & Celiac == 1, 1,
                       ifelse(FamilyID == "F0348" & Celiac == 0, 0,
                              ifelse(random_index == 1, 1, 0)))) %>%
  select(FamilyID, RecordID, MEGA.IID, MEGA.LabID, N_RecordIDs_per_FamilyID, index_within_FamilyID, random_index, Keep, everything()) %>%
  arrange(FamilyID, index_within_FamilyID) %>%
  filter(Keep == 1)
relateds_to_keep
relateds_to_keep$MEGA.IID
[1] "WG1-DNA_F10_HTP0295A"  "WG1-DNA_H05_HTP0262A"  "WG3-DNA_C03_HTP0333A3" "WG2-DNA_G10_HTP0480A"  "WG3-DNA_C05_HTP0432A"  "WG3-DNA_F05_HTP0566A" 

Update the EXCLUDE_from_analysis and EXCLUDE_reason columns to indicate which IIDs to exclude within multiple-IID FamilyIDs

meta.MEGA.T21_visit1_Celiac03 <- meta.MEGA.T21_visit1_Celiac02 %>%
  select(FamilyID, RecordID) %>% #, MEGA.IID, MEGA.LabID) %>%
  unique() %>%
  group_by(FamilyID) %>%
  mutate(N_RecordIDs_per_FamilyID = n()) %>%
  ungroup() %>%
  arrange(desc(N_RecordIDs_per_FamilyID)) %>%
  mutate(Multi_IID_FamilyID = ifelse(N_RecordIDs_per_FamilyID > 1, 1, 0)) %>%
  left_join(meta.MEGA.T21_visit1_Celiac02, by = c("FamilyID", "RecordID")) %>%
  mutate(Keep_from_Multi_IID_FamilyID = ifelse(MEGA.IID %in% relateds_to_keep$MEGA.IID, 1, 0)) %>%
  mutate(EXCLUDE_reason = gsub("[.]", "", EXCLUDE_reason)) %>%
  #filter(Multi_IID_FamilyID==1) %>% select(FamilyID, RecordID, N_RecordIDs_per_FamilyID, MEGA.IID, Keep_from_Multi_IID_FamilyID) %>% unique() %>% arrange(FamilyID, desc(Keep_from_Multi_IID_FamilyID))
  mutate(EXCLUDE_from_analysis = ifelse(Multi_IID_FamilyID == 1 & Keep_from_Multi_IID_FamilyID == 0, 1, EXCLUDE_from_analysis),
         EXCLUDE_reason = ifelse(is.na(EXCLUDE_reason) & Multi_IID_FamilyID == 1 & EXCLUDE_from_analysis == 1, "FamilyID with multiple RecordIDs",
                                 ifelse(!is.na(EXCLUDE_reason) & 
                                          Multi_IID_FamilyID == 1 &
                                          EXCLUDE_from_analysis == 1,
                                        paste(EXCLUDE_reason, "; FamilyID with multiple RecordIDs", sep = ""), EXCLUDE_reason))) %>%
  select(-c(Keep_from_Multi_IID_FamilyID)) %>%
  rename(N_T21_RecordIDs_in_FamilyID = N_RecordIDs_per_FamilyID) %>%
  select(FamilyID, RecordID, MEGA.FID, MEGA.IID, MEGA.LabID, Multi_IID_FamilyID, N_T21_RecordIDs_in_FamilyID, everything()) #%>%
  #mutate(EXCLUDE_from_analysis = ifelse(is.na(EXCLUDE_from_analysis), 0, EXCLUDE_from_analysis))

meta.MEGA.T21_visit1_Celiac03

meta.MEGA.T21_visit1_Celiac03 %>%
  select(FamilyID, RecordID, MEGA.FID, MEGA.IID, MEGA.LabID,
         Multi_IID_FamilyID, N_T21_RecordIDs_in_FamilyID, Celiac, EXCLUDE_from_analysis, EXCLUDE_reason) %>%
  unique() %>%
  arrange(desc(Celiac), desc(EXCLUDE_from_analysis))

Verify that the EXCLUDE variable is working correctly

Not excluding any Celiac cases unless they represent a RecordID genotyped twice on MEGA. Producing a dataset with only one MEGA.IID per RecordID. Producing a dataset with only one RecordID per FamilyID.

meta.MEGA.T21_visit1_Celiac03 %>%
  select(MEGA.IID, MEGA.LabID, Celiac, EXCLUDE_from_analysis, EXCLUDE_reason) %>%
  unique() %>%
  group_by(Celiac, EXCLUDE_from_analysis, EXCLUDE_reason) %>%
  summarise(N = n())
`summarise()` has grouped output by 'Celiac', 'EXCLUDE_from_analysis'. You can override using the `.groups` argument.
print("Good, not excluding any Celiac cases unless they represent a RecordID genotyped twice on MEGA.")
[1] "Good, not excluding any Celiac cases unless they represent a RecordID genotyped twice on MEGA."
print("Reasons we are currently excluding IIDs represented in the plink *.fam are:
      1) If the IID is for a RecordID that got genotyped twice, or
      2) If the IID is from a FamilyID with multiple genotyped individuals.")
[1] "Reasons we are currently excluding IIDs represented in the plink *.fam are:\n      1) If the IID is for a RecordID that got genotyped twice, or\n      2) If the IID is from a FamilyID with multiple genotyped individuals."
meta.MEGA.T21_visit1_Celiac03 %>%
  filter(EXCLUDE_from_analysis == 0) %>%
  select(RecordID, MEGA.IID) %>%
  unique() %>%
  group_by(RecordID) %>%
  summarise(N = n()) %>%
  arrange(desc(N))
print("Good, only one MEGA.IID per RecordID.")
[1] "Good, only one MEGA.IID per RecordID."
meta.MEGA.T21_visit1_Celiac03 %>%
  #filter(EXCLUDE_from_analysis == 0) %>%
  select(FamilyID, RecordID, MEGA.IID) %>%
  unique() %>%
  group_by(FamilyID, RecordID, MEGA.IID) %>%
  summarise(N = n()) %>%
  arrange(desc(N))
`summarise()` has grouped output by 'FamilyID', 'RecordID'. You can override using the `.groups` argument.
print("Good, only one RecordID per FamilyID.")
[1] "Good, only one RecordID per FamilyID."

View who is being excluded at this stage and why

meta.MEGA.T21_visit1_Celiac03 %>%
  select(FamilyID, RecordID, MEGA.FID, MEGA.IID, MEGA.LabID, Celiac, EXCLUDE_from_analysis, EXCLUDE_reason) %>%
  unique() %>%
  group_by(EXCLUDE_from_analysis, EXCLUDE_reason, Celiac) %>%
  summarise(N = n())
`summarise()` has grouped output by 'EXCLUDE_from_analysis', 'EXCLUDE_reason'. You can override using the `.groups` argument.
meta.MEGA.T21_visit1_Celiac03 %>%
  select(FamilyID, RecordID, MEGA.FID, MEGA.IID, MEGA.LabID, EXCLUDE_from_analysis, EXCLUDE_reason, Karyotype, Celiac, Sex) %>%
  unique() %>%
  group_by(EXCLUDE_from_analysis, EXCLUDE_reason, Karyotype, Celiac, Sex) %>%
  summarise(N = n()) %>%
  ungroup() %>%
  #filter(#EXCLUDE_from_analysis == 0 &
  #         !is.na(Celiac)) %>%
  mutate(Total = sum(N),
         Pct = round(100*N/Total, digits = 2)) %>%
  mutate(`N (%)` = paste(N, " (", Pct, ")", sep = "")) %>%
  select(EXCLUDE_from_analysis, EXCLUDE_reason, Karyotype, Celiac, Sex, `N (%)`) %>%
  mutate(Group = ifelse(Celiac == 0, "T21 without CD",
                        ifelse(Celiac == 1, "T21 with CD", NA))) %>%
  select(EXCLUDE_from_analysis, EXCLUDE_reason, Group, Sex, `N (%)`)
`summarise()` has grouped output by 'EXCLUDE_from_analysis', 'EXCLUDE_reason', 'Karyotype', 'Celiac'. You can override using the `.groups` argument.

Save to files

setwd(dir)
Warning: The working directory was changed to /Users/shawjes/Dropbox/EspinosaGroup/ANALYSIS/Celiac_MultiOmics/GRS/DSMIG_Shared/Manuscript_Figure1/Data inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
fwrite(meta.MEGA.T21_visit1_Celiac03, "MEGA_041822_META_CeliacGRS_v0.1_JRS.csv")
fwrite(meta.MEGA.T21_visit1_Celiac03, "MEGA_041822_META_CeliacGRS_v0.1_JRS.tsv", sep = "\t")
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyBGT0xMT1ctVVAgLS0gQWRkIHByZWFtYmxlIHRvIGVhY2ggTWFrZURhdGEgc2NyaXB0CiMjIyMgR29hbHMKSW5pdGlhbGl6ZSBtZXRhZGF0YSBmb3IgdGhlIEdSUyBhbmFseXNlcwpJZGVudGlmeSBpbmRpdmlkdWFscyB3aG8gYXJlIGVsaWdpYmxlIGZvciBhbmFseXNpcyBiYXNlZCBvbiBoYXZpbmcga25vd24gQ2VsaWFjIHN0YXR1cyBhbmQgbm8ga25vd24gZmlyc3QgZGVncmVlIHJlbGF0aXZlcyBpbiB0aGUgYW5hbHlzaXMgY29ob3J0CgojIyMjIExvYWQgZnJlcXVlbnRseSB1c2VkIHBhY2thZ2VzCmBgYHtyfQpsaWJyYXJ5KG9wZW54bHN4KQpsaWJyYXJ5KGdncmVwZWwpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShicm9vbSkKbGlicmFyeShicm9vbUV4dHJhKQpsaWJyYXJ5KHRpYmJsZSkKbGlicmFyeShzanN0YXRzKQpsaWJyYXJ5KGNhcikKbGlicmFyeShsbWU0KQpsaWJyYXJ5KGxtZXJUZXN0KQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KG1vZGVscikKbGlicmFyeSh0aWR5dmVyc2UpCiNsaWJyYXJ5KG1pY2VhZGRzKQpsaWJyYXJ5KGdnZm9yY2UpCnJlcXVpcmUob3Blbnhsc3gpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGNhcmV0KQpsaWJyYXJ5KGdsbW5ldCkKbGlicmFyeShnZ3Bsb3QyKQpzZWxlY3QgPC0gZHBseXI6OnNlbGVjdApmaWx0ZXIgPC0gZHBseXI6OmZpbHRlcgpgYGAKCiMjIyMgUHJpbnQgc2Vzc2lvbiBpbmZvIGZvciByZXByb2R1Y2liaWxpdHkKYGBge3J9CnNlc3Npb25JbmZvKCkKYGBgCgojIyMjIERlZmluZSBpbi9vdXQgZGlyZWN0b3J5CmBgYHtyfQpkaXIgPC0gIi9Vc2Vycy9zaGF3amVzL0Ryb3Bib3gvRXNwaW5vc2FHcm91cC9BTkFMWVNJUy9DZWxpYWNfTXVsdGlPbWljcy9HUlMvRFNNSUdfU2hhcmVkL01hbnVzY3JpcHRfRmlndXJlMS9EYXRhIgpgYGAKCiMjIyMgTG9hZCBNRUdBIHRvIEhUUCBJRCBrZXkKYGBge3J9CnNldHdkKGRpcikKTUVHQS5JRGtleSA8LSBmcmVhZCgiTUVHQV8wNDE4MjJfTUVHQTJfdG9fSFRQX0lEX2tleV92MC4xX0pSUy5jc3YiKQoKTUVHQS5JRGtleQpgYGAKCiMjIyMgUmVhZCBpbiBsYXRlc3QgdmVyc2lvbiBvZiB0aGUgbWV0YS9jb21vcmIgZGF0YQpgYGB7cn0Kc2V0d2QoIi9Vc2Vycy9zaGF3amVzL0Ryb3Bib3gvRXNwaW5vc2FHcm91cC9EQVRBX01BSU4vTUVUQS9PbmVEcml2ZV8xXzItMTctMjAyMiIpCm1ldGFfY29tb3JiLjAyMjAyMSA8LSBmcmVhZCgiSFRQX0NMRUFORURfMDJfMjAyMV92MC41X0NPTU9SQl9NQVNURVJfUmVjb3JkSURfdnNfTGFiSUQuTGFiZWxzLnRzdiIpICU+JQogIHNlbGVjdChGYW1pbHlJRCwgUmVjb3JkSUQsIExhYklELCBBZ2VfYXRfdmlzaXQsIFNleCwgS2FyeW90eXBlLCBldmVyeXRoaW5nKCkpICU+JQogIG11dGF0ZShDZWxpYWMgPSBhcy5udW1lcmljKGBDZWxpYWMgZGlzZWFzZWApKQoKbWV0YV9jb21vcmIuMDIyMDIxCmBgYAoKIyMjIyBQdXQgdGhlIGNvbHVtbiBuYW1lcyByZXByZXNlbnRpbmcgaWRlbnRpZmllcnMgaW50byBhIHZlY3RvciBmb3IgcmVmZXJlbmNlIGJlbG93CmBgYHtyfQpJRF9jb2xuYW1lcyA8LSBjKCJGYW1pbHlJRCIsICJSZWNvcmRJRCIsICJNRUdBLkZJRCIsICJNRUdBLklJRCIsICJNRUdBLkxhYklEIikKYGBgCgojIyMjIE1ha2Ugc3Vic2V0IG9mIG1ldGEvY29tb3JiIGRhdGFzZXQgc3BlY2lmaWMgdG8gVmlzaXQgMSBmb3IgVDIxcyB3aXRoIGNvbXBsZXRlIENlbGlhYyBzdGF0dXMKYGBge3J9Cm1ldGFfY29tb3JiLlQyMV92aXNpdDFfQ2VsaWFjIDwtIG1ldGFfY29tb3JiLjAyMjAyMSAlPiUKICBmaWx0ZXIoS2FyeW90eXBlID09ICJUMjEiICYKICAgICAgICAgICAhaXMubmEoTGFiSUQpICYgRXZlbnRfbmFtZSA9PSAiVmlzaXQgMSIgJiAjIEFzc3VtaW5nIHRoYXQgQ2VsaWFjIHN0YXR1cyBmb3IgSFRQIHdhcyBhc2NlcnRhaW5lZCBhcyBvZiBwYXJ0aWNpcGFudCB2aXNpdCAxCiAgICAgICAgICAgIWlzLm5hKGBDZWxpYWMgZGlzZWFzZWApKSAlPiUKICBzZWxlY3QoY29sbmFtZXMobWV0YV9jb21vcmIuMDIyMDIxKVsxOjE4XSwKICAgICAgICAgYENlbGlhYyBkaXNlYXNlYCwgQ2VsaWFjLAogICAgICAgICBldmVyeXRoaW5nKCkpICU+JQogIHJlbmFtZShBZ2VfYXRfdmlzaXQxID0gQWdlX2F0X3Zpc2l0KQoKbWV0YV9jb21vcmIuVDIxX3Zpc2l0MV9DZWxpYWMKYGBgCgojIyMjIE1ha2UgbWV0YS9jb21vcmIgZGF0YXNldCBzcGVjaWZpYyB0byB2aXNpdCAxIGZvciBUMjFzIHdpdGggY29tcGxldGUgQ2VsaWFjIHN0YXR1cyBhbmQgY29tcGxldGUgTUVHQSBnZW5vdHlwaW5nCmBgYHtyfQojY29sbmFtZXMoTUVHQS5JRGtleSkKI2NvbG5hbWVzKG1ldGFfY29tb3JiLjAyMjAyMSkKCm1ldGEuTUVHQS5UMjFfdmlzaXQxX0NlbGlhYyA8LSBNRUdBLklEa2V5ICU+JQogIGZpbHRlcihIVFBfcGFydGljaXBhbnQgPT0gIlllcyIpICU+JQogIHNlbGVjdCgtYyhIVFBfcGFydGljaXBhbnQpKSAlPiUKICBsZWZ0X2pvaW4obWV0YV9jb21vcmIuVDIxX3Zpc2l0MV9DZWxpYWMgJT4lIG11dGF0ZShJbl9UMjFjZWxpYWNfbWV0YWRhdGEgPSAxKSwKICAgICAgICAgICAgYnkgPSBjKCJGYW1pbHlJRCIsICJSZWNvcmRJRCIpKQojIE5vdGU6IEhlcmUgSSdtIGpvaW5pbmcgdG8gdGhlIG1ldGFkYXRhIGNvcnJlc3BvbmRpbmcgdG8gdmlzaXQgMSwgd2hlbiBDZWxpYWMgc3RhdHVzIHdhcyBkZXRlcm1pbmVkIGZvciB0aGUgcHVycG9zZXMgb2YgdGhlIHN0dWR5LiAKIyBGb3IgdGhpcyByZWFzb24gSSBhbSBub3QgaW5jbHVkaW5nIExhYklEIGFzIGEgam9pbiBieSB2YXJpYWJsZS4KCm1ldGEuTUVHQS5UMjFfdmlzaXQxX0NlbGlhYyAlPiUKICBncm91cF9ieShJbl9wbGlua19mYW0sIEluX1QyMWNlbGlhY19tZXRhZGF0YSkgJT4lCiAgc3VtbWFyaXNlKE4gPSBuKCkpCnByaW50KCI2IHBhcnRpY2lwYW50cyBoYXZlIGNvbXBsZXRlIGdlbm90eXBlIGRhdGEgYnV0IGluY29tcGxldGUgQ2VsaWFjIHN0YXR1cy4iKQoKbWV0YS5NRUdBLlQyMV92aXNpdDFfQ2VsaWFjMDEgPC0gbWV0YS5NRUdBLlQyMV92aXNpdDFfQ2VsaWFjICU+JQogIGZpbHRlcighaXMubmEoSW5fcGxpbmtfZmFtKSAmICFpcy5uYShJbl9UMjFjZWxpYWNfbWV0YWRhdGEpKSAlPiUKICBzZWxlY3QoLWMoSW5fcGxpbmtfZmFtLCBJbl9UMjFjZWxpYWNfbWV0YWRhdGEpKQoKbWV0YS5NRUdBLlQyMV92aXNpdDFfQ2VsaWFjMDEKYGBgCgojIyMjIERlZmluZSBjdXN0b20gZnVuY3Rpb24gZm9yIG1vZGUKYGBge3J9CiMgQ3JlYXRlIHRoZSBmdW5jdGlvbi4KZ2V0bW9kZSA8LSBmdW5jdGlvbih2KSB7CiAgIHVuaXF2IDwtIHVuaXF1ZSh2KQogICB1bmlxdlt3aGljaC5tYXgodGFidWxhdGUobWF0Y2godiwgdW5pcXYpKSldCn0KYGBgCgojIyMjIENoZWNrIHRoYXQgZWFjaCBpbmRpdmlkdWFsIHdhcyBvbmx5IGdlbm90eXBlZCBvbmUgdGltZQpgYGB7cn0KaWYoIChtZXRhLk1FR0EuVDIxX3Zpc2l0MV9DZWxpYWMwMSAlPiUKICAgICBncm91cF9ieShSZWNvcmRJRCkgJT4lCiAgICAgc3VtbWFyaXNlKE4gPSBuKCkpICU+JQogICAgIGFycmFuZ2UoZGVzYyhOKSkgJT4lCiAgICAgdW5ncm91cCgpICU+JQogICAgIHN1bW1hcmlzZSh2YXIoTikpID09IDApICkgeyJHcmVhdCwgYWxsIFJlY29yZElEcyBoYXZlIHRoZSBzYW1lIG51bWJlciBvZiByb3dzIG9mIGRhdGEuIn0gZWxzZSB7CiAgICAgICBwcmludCgiT29wcywgUmVjb3JkSURzIGhhdmUgdmFyeWluZyBudW1iZXIgb2Ygcm93cy4iKTsKICAgICAgIHRlbXAgPC0gbWV0YS5NRUdBLlQyMV92aXNpdDFfQ2VsaWFjMDEgJT4lCiAgICAgICAgIGdyb3VwX2J5KFJlY29yZElEKSAlPiUKICAgICAgICAgc3VtbWFyaXNlKE5fcm93cyA9IG4oKSkgJT4lCiAgICAgICAgIGFycmFuZ2UoZGVzYyhOX3Jvd3MpKSAlPiUKICAgICAgICAgdW5ncm91cCgpICU+JQogICAgICAgICBtdXRhdGUobWluLk5fcm93cyA9IG1pbihOX3Jvd3MpLAogICAgICAgICAgICAgICAgbWF4Lk5fcm93cyA9IG1heChOX3Jvd3MpLAogICAgICAgICAgICAgICAgbW9kZS5OX3Jvd3MgPSBnZXRtb2RlKE5fcm93cyksCiAgICAgICAgICAgICAgICBOX3Jvd3NfRXF1YWxfbW9kZSA9IGlmZWxzZShOX3Jvd3MgPT0gbW9kZS5OX3Jvd3MsIDEsIDApLAogICAgICAgICAgICAgICAgTl9yb3dzX05vdEVxdWFsX21vZGUgPSBpZmVsc2UoTl9yb3dzICE9IG1vZGUuTl9yb3dzLCAxLCAwKSkKICAgICAgIHByaW50KHBhc3RlKCJOID0gIiwgc3VtKHRlbXAkTl9yb3dzX0VxdWFsX21vZGUpLCAiIFJlY29yZElEcyB3aXRoIE5fcm93cyA9ICIsIHVuaXF1ZSh0ZW1wJG1vZGUuTl9yb3dzKSwgc2VwID0gIiIpKQogICAgICAgcHJpbnQocGFzdGUoIk4gPSAiLCBzdW0odGVtcCROX3Jvd3NfTm90RXF1YWxfbW9kZSksCiAgICAgICAgICAgICAgICAgICAiIFJlY29yZElEcyB3aXRoIG1lYW4gTl9yb3dzID0gIiwKICAgICAgICAgICAgICAgICAgIG1lYW4oKHRlbXAgJT4lIGZpbHRlcihOX3Jvd3MhPW1vZGUuTl9yb3dzKSkkTl9yb3dzKSwKICAgICAgICAgICAgICAgICAgICJcblByaW50aW5nIHByb2JsZW1hdGljIFJlY29yZElEcyBub3cuIFByb2JsZW1zIHN0b3JlZCBpbiBgcHJvYmxlbXNgIiwKICAgICAgICAgICAgICAgICAgIHNlcCA9ICIiKSkKICAgICAgICNwcmludChwYXN0ZSgiTiA9ICIsIHN1bSh0ZW1wJE5fRXF1YWxfbW9kZVsxXSksICIgc2FtcGxlcyB3aXRoIG5yb3cgPSAiLCB0ZW1wJE4sIHNlcCA9ICIiKSkKICAgICAgIAogICAgICAgcHJvYmxlbXMgPC0gdGVtcCAlPiUKICAgICAgICAgZmlsdGVyKE5fcm93cyAhPSBtb2RlLk5fcm93cykgJT4lCiAgICAgICAgIHNlbGVjdChSZWNvcmRJRCwgTl9yb3dzLCBtb2RlLk5fcm93cykgJT4lCiAgICAgICAgIGxlZnRfam9pbihtZXRhLk1FR0EuVDIxX3Zpc2l0MV9DZWxpYWMwMSwgYnkgPSAiUmVjb3JkSUQiKSAlPiUKICAgICAgICAgc2VsZWN0KEZhbWlseUlELCBSZWNvcmRJRCwgTUVHQS5JSUQsIE1FR0EuTGFiSUQsIE5fcm93cywgbW9kZS5OX3Jvd3MpICU+JQogICAgICAgICB1bmlxdWUoKQogICAgICAgCiAgICAgICBwcmludChwcm9ibGVtcykKICAgICB9CgpwcmludCgiQmFzZWQgb24gdGhpcyBvdXRwdXQsIGZpdmUgc2FtcGxlcyB3ZXJlIGdlbm90eXBlZCB0d2ljZSBpbiBkaWZmZXJlbnQgd2VsbHMuIikKcHJpbnQoIkJlbG93IHdlIHdpbGwgY2xlYW4gdGhlIGRhdGEgdG8ga2VlcCBvbmx5IHRoZSBmaXJzdCBzYW1wbGUgd2VsbCBmb3IgZWFjaCBSZWNvcmRJRC4iKQpgYGAKCiMjIyMgU2luY2Ugc29tZSBSZWNvcmRJRHMvTGFiSURzIHdlcmUgZ2Vub3R5cGVkIGluIG1vcmUgdGhhbiBvbmUgd2VsbCwgc29ydCBNRUdBLklJRCBhbHBoYWJldGljYWxseSB3aXRoaW4gUmVjb3JkSUQgYW5kIHRoZW4ga2VlcCB0aGUgZmlyc3QgTUVHQS5JSUQKYGBge3J9CiMgRk9MTE9XIFVQOiBEb3VibGUgY2hlY2sgaWYgdGhlIHBhcnRpY2lwYW50IGdlbm90eXBlZCB0d2ljZSBoYXMgY29tcGxldGUgZ2Vub3R5cGVzIGluIGJvdGggc2V0cyBvZiBnZW5vdHlwZXMuCgptZXRhLk1FR0EuVDIxX3Zpc2l0MV9DZWxpYWMwMiA8LSBtZXRhLk1FR0EuVDIxX3Zpc2l0MV9DZWxpYWMwMSAlPiUKICBzZWxlY3QoUmVjb3JkSUQsIE1FR0EuSUlEKSAlPiUKICB1bmlxdWUoKSAlPiUKICBncm91cF9ieShSZWNvcmRJRCkgJT4lCiAgYXJyYW5nZShNRUdBLklJRCkgJT4lCiAgbXV0YXRlKGluZGV4X01FR0EuSUlEX2Zvcl9SZWNvcmRJRCA9IHJvd19udW1iZXIoKSkgJT4lCiAgdW5ncm91cCgpICU+JQogICNhcnJhbmdlKGRlc2MoaW5kZXhfTUVHQS5JSURfZm9yX1JlY29yZElEKSkgJT4lCiAgZnVsbF9qb2luKG1ldGEuTUVHQS5UMjFfdmlzaXQxX0NlbGlhYzAxLCBieSA9IGMoIlJlY29yZElEIiwgIk1FR0EuSUlEIikpICU+JQogIG11dGF0ZShFWENMVURFX2Zyb21fYW5hbHlzaXMgPSBpZmVsc2UoaW5kZXhfTUVHQS5JSURfZm9yX1JlY29yZElEID4gMSwgMSwgMCksCiAgICAgICAgIEVYQ0xVREVfcmVhc29uID0gaWZlbHNlKEVYQ0xVREVfZnJvbV9hbmFseXNpcyA9PSAxICYgaW5kZXhfTUVHQS5JSURfZm9yX1JlY29yZElEID4xLCAiUmVjb3JkSUQgZ2Vub3R5cGVkIHR3aWNlLiIsIE5BKSkKCm1ldGEuTUVHQS5UMjFfdmlzaXQxX0NlbGlhYzAyICU+JQogIHNlbGVjdChGYW1pbHlJRCwgUmVjb3JkSUQsIE1FR0EuRklELCBNRUdBLklJRCwgTUVHQS5MYWJJRCwKICAgICAgICAgaW5kZXhfTUVHQS5JSURfZm9yX1JlY29yZElELCBFWENMVURFX2Zyb21fYW5hbHlzaXMsIEVYQ0xVREVfcmVhc29uLCBldmVyeXRoaW5nKCkpICU+JQogIGFycmFuZ2UoUmVjb3JkSUQsIGluZGV4X01FR0EuSUlEX2Zvcl9SZWNvcmRJRCkKYGBgCgojIyMjIENoZWNrIGlmIG5vdyBlYWNoIFJlY29yZElEIGhhcyBvbmx5IG9uZSBNRUdBLklJRApgYGB7cn0KcHJpbnQocGFzdGUoIlJvd3MgaW4gYG1lZ2FfU25wX2Rvc2FnZS5jbGVhbjAxYCA9ICIsIG1ldGEuTUVHQS5UMjFfdmlzaXQxX0NlbGlhYzAxICU+JSBzZWxlY3QoUmVjb3JkSUQsIE1FR0EuSUlEKSAlPiUgdW5pcXVlKCkgJT4lIG5yb3coKSwgc2VwID0gIiIpKQpwcmludChwYXN0ZSgiUm93cyBpbiBgbWVnYV9TbnBfZG9zYWdlLmNsZWFuMDJgID0gIiwgbWV0YS5NRUdBLlQyMV92aXNpdDFfQ2VsaWFjMDIgJT4lIGZpbHRlcihFWENMVURFX2Zyb21fYW5hbHlzaXMgPT0gMCkgJT4lIHNlbGVjdChSZWNvcmRJRCwgTUVHQS5JSUQpICU+JSB1bmlxdWUoKSAlPiUgbnJvdygpLCBzZXAgPSAiIikpCgppZiggKG1ldGEuTUVHQS5UMjFfdmlzaXQxX0NlbGlhYzAyICU+JSBmaWx0ZXIoRVhDTFVERV9mcm9tX2FuYWx5c2lzID09IDApICU+JQogICAgIGdyb3VwX2J5KFJlY29yZElEKSAlPiUKICAgICBzdW1tYXJpc2UoTiA9IG4oKSkgJT4lCiAgICAgYXJyYW5nZShkZXNjKE4pKSAlPiUKICAgICB1bmdyb3VwKCkgJT4lCiAgICAgc3VtbWFyaXNlKHZhcihOKSkgPT0gMCkgKSB7IkdyZWF0LCBub3cgYWxsIFJlY29yZElEcyBoYXZlIHRoZSBzYW1lIG51bWJlciBvZiByb3dzIG9mIGRhdGEuIn0gZWxzZSB7CiAgICAgICBwcmludCgiT29wcywgUmVjb3JkSURzIGhhdmUgdmFyeWluZyBudW1iZXIgb2Ygcm93cy4iKTsKICAgICAgIHRlbXAgPC0gbWV0YS5NRUdBLlQyMV92aXNpdDFfQ2VsaWFjMDIgJT4lIGZpbHRlcihFWENMVURFX2Zyb21fYW5hbHlzaXMgPT0gMCkgJT4lCiAgICAgICAgIGdyb3VwX2J5KFJlY29yZElEKSAlPiUKICAgICAgICAgc3VtbWFyaXNlKE5fcm93cyA9IG4oKSkgJT4lCiAgICAgICAgIGFycmFuZ2UoZGVzYyhOX3Jvd3MpKSAlPiUKICAgICAgICAgdW5ncm91cCgpICU+JQogICAgICAgICBtdXRhdGUobWluLk5fcm93cyA9IG1pbihOX3Jvd3MpLAogICAgICAgICAgICAgICAgbWF4Lk5fcm93cyA9IG1heChOX3Jvd3MpLAogICAgICAgICAgICAgICAgbW9kZS5OX3Jvd3MgPSBnZXRtb2RlKE5fcm93cyksCiAgICAgICAgICAgICAgICBOX3Jvd3NfRXF1YWxfbW9kZSA9IGlmZWxzZShOX3Jvd3MgPT0gbW9kZS5OX3Jvd3MsIDEsIDApLAogICAgICAgICAgICAgICAgTl9yb3dzX05vdEVxdWFsX21vZGUgPSBpZmVsc2UoTl9yb3dzICE9IG1vZGUuTl9yb3dzLCAxLCAwKSkKICAgICAgIHByaW50KHBhc3RlKCJOID0gIiwgc3VtKHRlbXAkTl9yb3dzX0VxdWFsX21vZGUpLCAiIFJlY29yZElEcyB3aXRoIE5fcm93cyA9ICIsIHVuaXF1ZSh0ZW1wJG1vZGUuTl9yb3dzKSwgc2VwID0gIiIpKQogICAgICAgcHJpbnQocGFzdGUoIk4gPSAiLCBzdW0odGVtcCROX3Jvd3NfTm90RXF1YWxfbW9kZSksCiAgICAgICAgICAgICAgICAgICAiIFJlY29yZElEcyB3aXRoIG1lYW4gTl9yb3dzID0gIiwKICAgICAgICAgICAgICAgICAgIG1lYW4oKHRlbXAgJT4lIGZpbHRlcihOX3Jvd3MhPW1vZGUuTl9yb3dzKSkkTl9yb3dzKSwKICAgICAgICAgICAgICAgICAgICJcblByaW50aW5nIHByb2JsZW1hdGljIFJlY29yZElEcyBub3cuIFByb2JsZW1zIHN0b3JlZCBpbiBgcHJvYmxlbXNgIiwKICAgICAgICAgICAgICAgICAgIHNlcCA9ICIiKSkKICAgICAgICNwcmludChwYXN0ZSgiTiA9ICIsIHN1bSh0ZW1wJE5fRXF1YWxfbW9kZVsxXSksICIgc2FtcGxlcyB3aXRoIG5yb3cgPSAiLCB0ZW1wJE4sIHNlcCA9ICIiKSkKICAgICAgIAogICAgICAgcHJvYmxlbXMgPC0gdGVtcCAlPiUKICAgICAgICAgZmlsdGVyKE5fcm93cyAhPSBtb2RlLk5fcm93cykgJT4lCiAgICAgICAgIHNlbGVjdChSZWNvcmRJRCwgTl9yb3dzLCBtb2RlLk5fcm93cykgJT4lCiAgICAgICAgIGxlZnRfam9pbihtZXRhLk1FR0EuVDIxX3Zpc2l0MV9DZWxpYWMwMiwgYnkgPSAiUmVjb3JkSUQiKSAlPiUKICAgICAgICAgc2VsZWN0KEZhbWlseUlELCBSZWNvcmRJRCwgTUVHQS5JSUQsIE1FR0EuTGFiSUQsIE5fcm93cywgbW9kZS5OX3Jvd3MpICU+JQogICAgICAgICB1bmlxdWUoKQogICAgICAgCiAgICAgICBwcmludChwcm9ibGVtcykKICAgICB9CmBgYAoKIyMjIyBJZiBhbGwgb2YgdGhlIGZvbGxvd2luZyBlcXVhbCB0aGUgc2FtZSBudW1iZXIgb2Ygcm93cywgdGhlbiB0aGlzIGRhdGFmcmFtZSBub3cgcmVwcmVzZW50cyBnZW5vdHlwaW5nIG9ubHkgb25jZSBwZXIgaW5kaXZpZHVhbApgYGB7cn0KbWV0YS5NRUdBLlQyMV92aXNpdDFfQ2VsaWFjMDIgJT4lIGZpbHRlcihFWENMVURFX2Zyb21fYW5hbHlzaXMgPT0gMCkgJT4lCiAgc2VsZWN0KEZhbWlseUlELCBSZWNvcmRJRCwgTUVHQS5JSUQsIE1FR0EuTGFiSUQpICU+JQogIHVuaXF1ZSgpICU+JQogIG5yb3coKQoKbWV0YS5NRUdBLlQyMV92aXNpdDFfQ2VsaWFjMDIgJT4lIGZpbHRlcihFWENMVURFX2Zyb21fYW5hbHlzaXMgPT0gMCkgJT4lCiAgc2VsZWN0KFJlY29yZElELCBNRUdBLklJRCwgTUVHQS5MYWJJRCkgJT4lCiAgdW5pcXVlKCkgJT4lCiAgbnJvdygpCgptZXRhLk1FR0EuVDIxX3Zpc2l0MV9DZWxpYWMwMiAlPiUgZmlsdGVyKEVYQ0xVREVfZnJvbV9hbmFseXNpcyA9PSAwKSAlPiUKICBzZWxlY3QoTUVHQS5JSUQsIE1FR0EuTGFiSUQpICU+JQogIHVuaXF1ZSgpICU+JQogIG5yb3coKQoKbWV0YS5NRUdBLlQyMV92aXNpdDFfQ2VsaWFjMDIgJT4lIGZpbHRlcihFWENMVURFX2Zyb21fYW5hbHlzaXMgPT0gMCkgJT4lCiAgc2VsZWN0KE1FR0EuTGFiSUQpICU+JQogIHVuaXF1ZSgpICU+JQogIG5yb3coKQoKbWV0YS5NRUdBLlQyMV92aXNpdDFfQ2VsaWFjMDIgJT4lIGZpbHRlcihFWENMVURFX2Zyb21fYW5hbHlzaXMgPT0gMCkgJT4lCiAgc2VsZWN0KE1FR0EuSUlEKSAlPiUKICB1bmlxdWUoKSAlPiUKICBucm93KCkKCm1ldGEuTUVHQS5UMjFfdmlzaXQxX0NlbGlhYzAyICU+JSBmaWx0ZXIoRVhDTFVERV9mcm9tX2FuYWx5c2lzID09IDApICU+JQogIHNlbGVjdChSZWNvcmRJRCkgJT4lCiAgdW5pcXVlKCkgJT4lCiAgbnJvdygpCgptZXRhLk1FR0EuVDIxX3Zpc2l0MV9DZWxpYWMwMiAlPiUgZmlsdGVyKEVYQ0xVREVfZnJvbV9hbmFseXNpcyA9PSAwKSAlPiUKICBzZWxlY3QoRmFtaWx5SUQsIFJlY29yZElELCBNRUdBLklJRCkgJT4lCiAgdW5pcXVlKCkgJT4lCiAgbnJvdygpCgptZXRhLk1FR0EuVDIxX3Zpc2l0MV9DZWxpYWMwMiAlPiUgZmlsdGVyKEVYQ0xVREVfZnJvbV9hbmFseXNpcyA9PSAwKSAlPiUKICBzZWxlY3QoRmFtaWx5SUQsIFJlY29yZElEKSAlPiUKICB1bmlxdWUoKSAlPiUKICBucm93KCkKCm1ldGEuTUVHQS5UMjFfdmlzaXQxX0NlbGlhYzAyICU+JSBmaWx0ZXIoRVhDTFVERV9mcm9tX2FuYWx5c2lzID09IDApICU+JQogIHNlbGVjdChSZWNvcmRJRCwgTUVHQS5JSUQpICU+JQogIHVuaXF1ZSgpICU+JQogIG5yb3coKQoKcHJpbnQoIklmIGFsbCBvZiB0aGUgbnVtYmVycyBwcmludGVkIGFib3ZlIGVxdWFsIHRoZSBzYW1lIG51bWJlciBvZiByb3dzLCB0aGVuIHRoaXMgZGF0YWZyYW1lIG5vdyByZXByZXNlbnRzIGdlbm90eXBpbmcgb25seSBvbmNlIHBlciBpbmRpdmlkdWFsLiIpCnByaW50KCJHb29kLiIpCmBgYAoKIyMjIyBGaW5hbCBjaGVjayB0aGF0IGFsbCBSZWNvcmRJRHMgbm93IGhhdmUgb25seSAxIE1FR0EuSUlEIGFmdGVyIHVzaW5nIHRoZSBFWENMVURFX2Zyb21fYW5hbHlzaXMgY29sdW1uIHRvIGZpbHRlcgpgYGB7cn0KbWV0YS5NRUdBLlQyMV92aXNpdDFfQ2VsaWFjMDIgJT4lIGZpbHRlcihFWENMVURFX2Zyb21fYW5hbHlzaXMgPT0gMCkgJT4lCiAgc2VsZWN0KFJlY29yZElELCBNRUdBLklJRCkgJT4lCiAgdW5pcXVlKCkgJT4lCiAgZ3JvdXBfYnkoUmVjb3JkSUQpICU+JQogIHN1bW1hcmlzZShOID0gbigpKSAlPiUKICBhcnJhbmdlKGRlc2MoTikpICU+JQogIGxlZnRfam9pbihtZXRhLk1FR0EuVDIxX3Zpc2l0MV9DZWxpYWMwMiwgYnkgPSAiUmVjb3JkSUQiKSAlPiUKICBmaWx0ZXIoTiA+IDEpCgpwcmludCgiR29vZC4gQWxsIFJlY29yZElEcyBoYXZlIG9ubHkgMSBNRUdBLklJRCBhZnRlciBhcHBseWluZyB0aGUgRVhDTFVERV9mcm9tX2FuYWx5c2lzIGZpbHRlci4iKQpgYGAKCiMjIyMgQ2hlY2sgZm9yIHR3aW5zIGFuZCBvdGhlciByZWxhdGVkcwojIyMjIElmIHRoZXJlIGFyZSByZWxhdGVkcyBpbiB0aGUgZGF0YXNldCBhZnRlciBhcHBseWluZyB0aGUgRVhDTFVERSBmaWx0ZXIsIGZpcnN0IHByaW9yaXRpemUga2VlcGluZyBDZWxpYWMgY2FzZXMsIHRoZW4gcmFuZG9tbHkgY2hvb3NlIG9uZSBJSUQgcGVyIEZhbWlseUlEIHRvIHJldGFpbiBmb3IgYW5hbHlzaXMKYGBge3J9Cm1ldGEuTUVHQS5UMjFfdmlzaXQxX0NlbGlhYzAyICU+JSBmaWx0ZXIoRVhDTFVERV9mcm9tX2FuYWx5c2lzID09IDApICU+JQogIHNlbGVjdChGYW1pbHlJRCwgUmVjb3JkSUQpICU+JSAjLCBNRUdBLklJRCwgTUVHQS5MYWJJRCkgJT4lCiAgdW5pcXVlKCkgJT4lCiAgZ3JvdXBfYnkoRmFtaWx5SUQpICU+JQogIHN1bW1hcmlzZShOX1JlY29yZElEc19wZXJfRmFtaWx5SUQgPSBuKCkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBhcnJhbmdlKGRlc2MoTl9SZWNvcmRJRHNfcGVyX0ZhbWlseUlEKSkgJT4lCiAgZmlsdGVyKE5fUmVjb3JkSURzX3Blcl9GYW1pbHlJRCA+IDEpCgpyZWxhdGVkcyA8LSBtZXRhLk1FR0EuVDIxX3Zpc2l0MV9DZWxpYWMwMiAlPiUgZmlsdGVyKEVYQ0xVREVfZnJvbV9hbmFseXNpcyA9PSAwKSAlPiUKICBzZWxlY3QoRmFtaWx5SUQsIFJlY29yZElEKSAlPiUgIywgTUVHQS5JSUQsIE1FR0EuTGFiSUQpICU+JQogIHVuaXF1ZSgpICU+JQogIGdyb3VwX2J5KEZhbWlseUlEKSAlPiUKICBzdW1tYXJpc2UoTl9SZWNvcmRJRHNfcGVyX0ZhbWlseUlEID0gbigpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgYXJyYW5nZShkZXNjKE5fUmVjb3JkSURzX3Blcl9GYW1pbHlJRCkpICU+JQogIGZpbHRlcihOX1JlY29yZElEc19wZXJfRmFtaWx5SUQgPiAxKSAlPiUKICBsZWZ0X2pvaW4obWV0YS5NRUdBLlQyMV92aXNpdDFfQ2VsaWFjMDIsIGJ5ID0gIkZhbWlseUlEIikgJT4lCiAgc2VsZWN0KEZhbWlseUlELCBOX1JlY29yZElEc19wZXJfRmFtaWx5SUQsIFJlY29yZElELCBNRUdBLklJRCwgTUVHQS5MYWJJRCwgRVhDTFVERV9mcm9tX2FuYWx5c2lzLCBDZWxpYWMsIFNleCwgQWdlX2F0X3Zpc2l0MSkgJT4lCiAgdW5pcXVlKCkgJT4lCiAgI2xlZnRfam9pbihtZXRhX2NvbW9yYi4wMjIwMjEsIGJ5ID0gYygiRmFtaWx5SUQiLCAiUmVjb3JkSUQiLCAiTUVHQS5MYWJJRCI9IkxhYklEIikpICU+JQogIGdyb3VwX2J5KEZhbWlseUlEKSAlPiUKICBhcnJhbmdlKGRlc2MoQ2VsaWFjKSkgJT4lCiAgbXV0YXRlKGluZGV4X3dpdGhpbl9GYW1pbHlJRCA9IHJvd19udW1iZXIoKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIHNlbGVjdChGYW1pbHlJRCwgTl9SZWNvcmRJRHNfcGVyX0ZhbWlseUlELCBpbmRleF93aXRoaW5fRmFtaWx5SUQsIENlbGlhYywgU2V4LCBBZ2VfYXRfdmlzaXQxLCBldmVyeXRoaW5nKCkpICU+JQogIGFycmFuZ2UoRmFtaWx5SUQsIGluZGV4X3dpdGhpbl9GYW1pbHlJRCkKCnJlbGF0ZWRzCgpyZWxhdGVkcyAlPiUKICBzZWxlY3QoRmFtaWx5SUQsIGluZGV4X3dpdGhpbl9GYW1pbHlJRCwgRVhDTFVERV9mcm9tX2FuYWx5c2lzLCBDZWxpYWMsIFNleCkgJT4lCiAgdW5pcXVlKCkgJT4lCiAgZ3JvdXBfYnkoRmFtaWx5SUQsIFNleCkgJT4lCiAgc3VtbWFyaXNlKE4gPSBuKCkpCgpwcmludCgiRGVjaXNpb246IEZyb20gRmFtaWx5SUQgRjAzNDggKDIgaW5kaXZpZHVhbHMpLCBrZWVwIElOVlRIMzI4SEE5IGJlY2F1c2UgdGhpcyBwZXJzb24gaXMgYSBDZWxpYWMgY2FzZS4iKQpwcmludCgiTm90ZTogQWxsIG90aGVyIGZhbWlseXMgaGF2ZSBvbmx5IG1hbGVzIG9yIG9ubHkgZmVtYWxlcywgZXhjZXB0IGZvciBvbmUgZmFtaWx5IHdpdGggMSBvZiBlYWNoLiIpCnByaW50KCJEZWNpc2lvbjogVGhlcmVmb3JlLCBmcm9tIGFsbCBvdGhlciBGYW1pbHlJRHMsIHJhbmRvbWx5IHNlbGVjdCBvbmUgaW5kaXZpZHVhbCB0byByZW1haW4gaW4gdGhlIGFuYWx5c2lzLiIpCgpzZXQuc2VlZCgxMjM0KSAjIFNldCBzZWVkIGZvciByYW5kb21seSBzaHVmZmxpbmcgcm93cwpyZWxhdGVkc190b19rZWVwID0gcmVsYXRlZHNbc2FtcGxlKDE6bnJvdyhyZWxhdGVkcykpLCBdICU+JQogIGdyb3VwX2J5KEZhbWlseUlEKSAlPiUKICBtdXRhdGUocmFuZG9tX2luZGV4ID0gcm93X251bWJlcigpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKEtlZXAgPSBpZmVsc2UoRmFtaWx5SUQgPT0gIkYwMzQ4IiAmIENlbGlhYyA9PSAxLCAxLAogICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShGYW1pbHlJRCA9PSAiRjAzNDgiICYgQ2VsaWFjID09IDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZShyYW5kb21faW5kZXggPT0gMSwgMSwgMCkpKSkgJT4lCiAgc2VsZWN0KEZhbWlseUlELCBSZWNvcmRJRCwgTUVHQS5JSUQsIE1FR0EuTGFiSUQsIE5fUmVjb3JkSURzX3Blcl9GYW1pbHlJRCwgaW5kZXhfd2l0aGluX0ZhbWlseUlELCByYW5kb21faW5kZXgsIEtlZXAsIGV2ZXJ5dGhpbmcoKSkgJT4lCiAgYXJyYW5nZShGYW1pbHlJRCwgaW5kZXhfd2l0aGluX0ZhbWlseUlEKSAlPiUKICBmaWx0ZXIoS2VlcCA9PSAxKQpyZWxhdGVkc190b19rZWVwCnJlbGF0ZWRzX3RvX2tlZXAkTUVHQS5JSUQKYGBgCgojIyMjIFVwZGF0ZSB0aGUgYEVYQ0xVREVfZnJvbV9hbmFseXNpc2AgYW5kIGBFWENMVURFX3JlYXNvbmAgY29sdW1ucyB0byBpbmRpY2F0ZSB3aGljaCBJSURzIHRvIGV4Y2x1ZGUgd2l0aGluIG11bHRpcGxlLUlJRCBGYW1pbHlJRHMKYGBge3J9Cm1ldGEuTUVHQS5UMjFfdmlzaXQxX0NlbGlhYzAzIDwtIG1ldGEuTUVHQS5UMjFfdmlzaXQxX0NlbGlhYzAyICU+JQogIHNlbGVjdChGYW1pbHlJRCwgUmVjb3JkSUQpICU+JSAjLCBNRUdBLklJRCwgTUVHQS5MYWJJRCkgJT4lCiAgdW5pcXVlKCkgJT4lCiAgZ3JvdXBfYnkoRmFtaWx5SUQpICU+JQogIG11dGF0ZShOX1JlY29yZElEc19wZXJfRmFtaWx5SUQgPSBuKCkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBhcnJhbmdlKGRlc2MoTl9SZWNvcmRJRHNfcGVyX0ZhbWlseUlEKSkgJT4lCiAgbXV0YXRlKE11bHRpX0lJRF9GYW1pbHlJRCA9IGlmZWxzZShOX1JlY29yZElEc19wZXJfRmFtaWx5SUQgPiAxLCAxLCAwKSkgJT4lCiAgbGVmdF9qb2luKG1ldGEuTUVHQS5UMjFfdmlzaXQxX0NlbGlhYzAyLCBieSA9IGMoIkZhbWlseUlEIiwgIlJlY29yZElEIikpICU+JQogIG11dGF0ZShLZWVwX2Zyb21fTXVsdGlfSUlEX0ZhbWlseUlEID0gaWZlbHNlKE1FR0EuSUlEICVpbiUgcmVsYXRlZHNfdG9fa2VlcCRNRUdBLklJRCwgMSwgMCkpICU+JQogIG11dGF0ZShFWENMVURFX3JlYXNvbiA9IGdzdWIoIlsuXSIsICIiLCBFWENMVURFX3JlYXNvbikpICU+JQogICNmaWx0ZXIoTXVsdGlfSUlEX0ZhbWlseUlEPT0xKSAlPiUgc2VsZWN0KEZhbWlseUlELCBSZWNvcmRJRCwgTl9SZWNvcmRJRHNfcGVyX0ZhbWlseUlELCBNRUdBLklJRCwgS2VlcF9mcm9tX011bHRpX0lJRF9GYW1pbHlJRCkgJT4lIHVuaXF1ZSgpICU+JSBhcnJhbmdlKEZhbWlseUlELCBkZXNjKEtlZXBfZnJvbV9NdWx0aV9JSURfRmFtaWx5SUQpKQogIG11dGF0ZShFWENMVURFX2Zyb21fYW5hbHlzaXMgPSBpZmVsc2UoTXVsdGlfSUlEX0ZhbWlseUlEID09IDEgJiBLZWVwX2Zyb21fTXVsdGlfSUlEX0ZhbWlseUlEID09IDAsIDEsIEVYQ0xVREVfZnJvbV9hbmFseXNpcyksCiAgICAgICAgIEVYQ0xVREVfcmVhc29uID0gaWZlbHNlKGlzLm5hKEVYQ0xVREVfcmVhc29uKSAmIE11bHRpX0lJRF9GYW1pbHlJRCA9PSAxICYgRVhDTFVERV9mcm9tX2FuYWx5c2lzID09IDEsICJGYW1pbHlJRCB3aXRoIG11bHRpcGxlIFJlY29yZElEcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSghaXMubmEoRVhDTFVERV9yZWFzb24pICYgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE11bHRpX0lJRF9GYW1pbHlJRCA9PSAxICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRVhDTFVERV9mcm9tX2FuYWx5c2lzID09IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZShFWENMVURFX3JlYXNvbiwgIjsgRmFtaWx5SUQgd2l0aCBtdWx0aXBsZSBSZWNvcmRJRHMiLCBzZXAgPSAiIiksIEVYQ0xVREVfcmVhc29uKSkpICU+JQogIHNlbGVjdCgtYyhLZWVwX2Zyb21fTXVsdGlfSUlEX0ZhbWlseUlEKSkgJT4lCiAgcmVuYW1lKE5fVDIxX1JlY29yZElEc19pbl9GYW1pbHlJRCA9IE5fUmVjb3JkSURzX3Blcl9GYW1pbHlJRCkgJT4lCiAgc2VsZWN0KEZhbWlseUlELCBSZWNvcmRJRCwgTUVHQS5GSUQsIE1FR0EuSUlELCBNRUdBLkxhYklELCBNdWx0aV9JSURfRmFtaWx5SUQsIE5fVDIxX1JlY29yZElEc19pbl9GYW1pbHlJRCwgZXZlcnl0aGluZygpKSAjJT4lCiAgI211dGF0ZShFWENMVURFX2Zyb21fYW5hbHlzaXMgPSBpZmVsc2UoaXMubmEoRVhDTFVERV9mcm9tX2FuYWx5c2lzKSwgMCwgRVhDTFVERV9mcm9tX2FuYWx5c2lzKSkKCm1ldGEuTUVHQS5UMjFfdmlzaXQxX0NlbGlhYzAzCgptZXRhLk1FR0EuVDIxX3Zpc2l0MV9DZWxpYWMwMyAlPiUKICBzZWxlY3QoRmFtaWx5SUQsIFJlY29yZElELCBNRUdBLkZJRCwgTUVHQS5JSUQsIE1FR0EuTGFiSUQsCiAgICAgICAgIE11bHRpX0lJRF9GYW1pbHlJRCwgTl9UMjFfUmVjb3JkSURzX2luX0ZhbWlseUlELCBDZWxpYWMsIEVYQ0xVREVfZnJvbV9hbmFseXNpcywgRVhDTFVERV9yZWFzb24pICU+JQogIHVuaXF1ZSgpICU+JQogIGFycmFuZ2UoZGVzYyhDZWxpYWMpLCBkZXNjKEVYQ0xVREVfZnJvbV9hbmFseXNpcykpCmBgYAoKIyMjIyBWZXJpZnkgdGhhdCB0aGUgRVhDTFVERSB2YXJpYWJsZSBpcyB3b3JraW5nIGNvcnJlY3RseQpOb3QgZXhjbHVkaW5nIGFueSBDZWxpYWMgY2FzZXMgdW5sZXNzIHRoZXkgcmVwcmVzZW50IGEgUmVjb3JkSUQgZ2Vub3R5cGVkIHR3aWNlIG9uIE1FR0EuClByb2R1Y2luZyBhIGRhdGFzZXQgd2l0aCBvbmx5IG9uZSBNRUdBLklJRCBwZXIgUmVjb3JkSUQuClByb2R1Y2luZyBhIGRhdGFzZXQgd2l0aCBvbmx5IG9uZSBSZWNvcmRJRCBwZXIgRmFtaWx5SUQuCmBgYHtyfQptZXRhLk1FR0EuVDIxX3Zpc2l0MV9DZWxpYWMwMyAlPiUKICBzZWxlY3QoTUVHQS5JSUQsIE1FR0EuTGFiSUQsIENlbGlhYywgRVhDTFVERV9mcm9tX2FuYWx5c2lzLCBFWENMVURFX3JlYXNvbikgJT4lCiAgdW5pcXVlKCkgJT4lCiAgZ3JvdXBfYnkoQ2VsaWFjLCBFWENMVURFX2Zyb21fYW5hbHlzaXMsIEVYQ0xVREVfcmVhc29uKSAlPiUKICBzdW1tYXJpc2UoTiA9IG4oKSkKcHJpbnQoIkdvb2QsIG5vdCBleGNsdWRpbmcgYW55IENlbGlhYyBjYXNlcyB1bmxlc3MgdGhleSByZXByZXNlbnQgYSBSZWNvcmRJRCBnZW5vdHlwZWQgdHdpY2Ugb24gTUVHQS4iKQpwcmludCgiUmVhc29ucyB3ZSBhcmUgY3VycmVudGx5IGV4Y2x1ZGluZyBJSURzIHJlcHJlc2VudGVkIGluIHRoZSBwbGluayAqLmZhbSBhcmU6CiAgICAgIDEpIElmIHRoZSBJSUQgaXMgZm9yIGEgUmVjb3JkSUQgdGhhdCBnb3QgZ2Vub3R5cGVkIHR3aWNlLCBvcgogICAgICAyKSBJZiB0aGUgSUlEIGlzIGZyb20gYSBGYW1pbHlJRCB3aXRoIG11bHRpcGxlIGdlbm90eXBlZCBpbmRpdmlkdWFscy4iKQoKbWV0YS5NRUdBLlQyMV92aXNpdDFfQ2VsaWFjMDMgJT4lCiAgZmlsdGVyKEVYQ0xVREVfZnJvbV9hbmFseXNpcyA9PSAwKSAlPiUKICBzZWxlY3QoUmVjb3JkSUQsIE1FR0EuSUlEKSAlPiUKICB1bmlxdWUoKSAlPiUKICBncm91cF9ieShSZWNvcmRJRCkgJT4lCiAgc3VtbWFyaXNlKE4gPSBuKCkpICU+JQogIGFycmFuZ2UoZGVzYyhOKSkKcHJpbnQoIkdvb2QsIG9ubHkgb25lIE1FR0EuSUlEIHBlciBSZWNvcmRJRC4iKQoKbWV0YS5NRUdBLlQyMV92aXNpdDFfQ2VsaWFjMDMgJT4lCiAgI2ZpbHRlcihFWENMVURFX2Zyb21fYW5hbHlzaXMgPT0gMCkgJT4lCiAgc2VsZWN0KEZhbWlseUlELCBSZWNvcmRJRCwgTUVHQS5JSUQpICU+JQogIHVuaXF1ZSgpICU+JQogIGdyb3VwX2J5KEZhbWlseUlELCBSZWNvcmRJRCwgTUVHQS5JSUQpICU+JQogIHN1bW1hcmlzZShOID0gbigpKSAlPiUKICBhcnJhbmdlKGRlc2MoTikpCnByaW50KCJHb29kLCBvbmx5IG9uZSBSZWNvcmRJRCBwZXIgRmFtaWx5SUQuIikKYGBgCgojIyMjIFZpZXcgd2hvIGlzIGJlaW5nIGV4Y2x1ZGVkIGF0IHRoaXMgc3RhZ2UgYW5kIHdoeQpgYGB7cn0KbWV0YS5NRUdBLlQyMV92aXNpdDFfQ2VsaWFjMDMgJT4lCiAgc2VsZWN0KEZhbWlseUlELCBSZWNvcmRJRCwgTUVHQS5GSUQsIE1FR0EuSUlELCBNRUdBLkxhYklELCBDZWxpYWMsIEVYQ0xVREVfZnJvbV9hbmFseXNpcywgRVhDTFVERV9yZWFzb24pICU+JQogIHVuaXF1ZSgpICU+JQogIGdyb3VwX2J5KEVYQ0xVREVfZnJvbV9hbmFseXNpcywgRVhDTFVERV9yZWFzb24sIENlbGlhYykgJT4lCiAgc3VtbWFyaXNlKE4gPSBuKCkpCgptZXRhLk1FR0EuVDIxX3Zpc2l0MV9DZWxpYWMwMyAlPiUKICBzZWxlY3QoRmFtaWx5SUQsIFJlY29yZElELCBNRUdBLkZJRCwgTUVHQS5JSUQsIE1FR0EuTGFiSUQsIEVYQ0xVREVfZnJvbV9hbmFseXNpcywgRVhDTFVERV9yZWFzb24sIEthcnlvdHlwZSwgQ2VsaWFjLCBTZXgpICU+JQogIHVuaXF1ZSgpICU+JQogIGdyb3VwX2J5KEVYQ0xVREVfZnJvbV9hbmFseXNpcywgRVhDTFVERV9yZWFzb24sIEthcnlvdHlwZSwgQ2VsaWFjLCBTZXgpICU+JQogIHN1bW1hcmlzZShOID0gbigpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgI2ZpbHRlcigjRVhDTFVERV9mcm9tX2FuYWx5c2lzID09IDAgJgogICMgICAgICAgICAhaXMubmEoQ2VsaWFjKSkgJT4lCiAgbXV0YXRlKFRvdGFsID0gc3VtKE4pLAogICAgICAgICBQY3QgPSByb3VuZCgxMDAqTi9Ub3RhbCwgZGlnaXRzID0gMikpICU+JQogIG11dGF0ZShgTiAoJSlgID0gcGFzdGUoTiwgIiAoIiwgUGN0LCAiKSIsIHNlcCA9ICIiKSkgJT4lCiAgc2VsZWN0KEVYQ0xVREVfZnJvbV9hbmFseXNpcywgRVhDTFVERV9yZWFzb24sIEthcnlvdHlwZSwgQ2VsaWFjLCBTZXgsIGBOICglKWApICU+JQogIG11dGF0ZShHcm91cCA9IGlmZWxzZShDZWxpYWMgPT0gMCwgIlQyMSB3aXRob3V0IENEIiwKICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKENlbGlhYyA9PSAxLCAiVDIxIHdpdGggQ0QiLCBOQSkpKSAlPiUKICBzZWxlY3QoRVhDTFVERV9mcm9tX2FuYWx5c2lzLCBFWENMVURFX3JlYXNvbiwgR3JvdXAsIFNleCwgYE4gKCUpYCkKYGBgCgojIyMjIFNhdmUgdG8gZmlsZXMKYGBge3J9CnNldHdkKGRpcikKZndyaXRlKG1ldGEuTUVHQS5UMjFfdmlzaXQxX0NlbGlhYzAzLCAiTUVHQV8wNDE4MjJfTUVUQV9DZWxpYWNHUlNfdjAuMV9KUlMuY3N2IikKZndyaXRlKG1ldGEuTUVHQS5UMjFfdmlzaXQxX0NlbGlhYzAzLCAiTUVHQV8wNDE4MjJfTUVUQV9DZWxpYWNHUlNfdjAuMV9KUlMudHN2Iiwgc2VwID0gIlx0IikKYGBgCg==